﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;

namespace JasLib.Wpf
{
    public static class WpfUtilities
    {
        /*****************************************************************************/
        public static string GeneratePropertyPathString(System.Linq.Expressions.Expression expression)
        {
            if (expression.NodeType == ExpressionType.Lambda)
            {
                var lambdaExpression = (expression as LambdaExpression);
                return GeneratePropertyPathString(lambdaExpression.Body);
            }

            /// Nothing wrong with a typecast; it doesn't change the essential definition.
            else if (expression.NodeType == ExpressionType.Convert)
            {
                var convertExpression = (expression as UnaryExpression);
                return GeneratePropertyPathString(convertExpression.Operand);
            }

            else if (expression.NodeType == ExpressionType.MemberAccess)
            {
                var memberExpression = (expression as MemberExpression);
                if (memberExpression != null && memberExpression.Member.MemberType == MemberTypes.Property)
                {
                    string strPath = string.Empty;

                    /// A property precedes it.
                    if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess)
                    {
                        strPath += GeneratePropertyPathString(memberExpression.Expression);
                        strPath += ".";
                    }
                    strPath += memberExpression.Member.Name;

                    return string.Intern(strPath);
                }
            }

            /// This is in principle a coding bug and not a runtime bug.
            Debugger.Break();
            throw new InvalidOperationException("The expression must return a WPF-compatible property path.");
        }
    }
}
